home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Keyframe Magazine 6
/
KeyFrame Magazine, Issue 6 - May-June 1998 WIN-MAC (David Warner)(1998).iso
/
mac
/
ProgHide
/
default.cpp
next >
Wrap
C/C++ Source or Header
|
1997-06-23
|
8KB
|
306 lines
//Includes
#include <splug.h>
#include <moni.h>
#include <lwran.h>
#include <lwpanel.h>
#include <strstrea.h>
//Typedefs
typedef unsigned short int USHORT;
//Defines
#define NULL 0
//Global constant (reduces string table size)
const char * const SPACE = " ";
//Function prototypes
//
extern "C"
{
int GRADActivate(long, GlobalFunc *, void *, void *);
int GRADInterface(long, GlobalFunc *, LWInstance, void *);
}
LWInstance GRADcreate(LWError *);
void GRADdestroy(LWInstance);
LWError GRADcopy(LWInstance, LWInstance);
LWError GRADload(LWInstance, const LWLoadState *);
LWError GRADsave(LWInstance, const LWSaveState *);
const char* GRADdescln(LWInstance);
void GRADprocess(LWInstance, const FilterAccess *);
unsigned int GRADflags(LWInstance);
//Most plugins have a structure or class they store data in. This is called the instance.
//
class GRADIENT
{
public:
//Gradient colors at the top and bottom of the image
USHORT cTop[3], cBottom[3];
private:
};
//The ServerRecord structure identifies all the plugins in this file to Lightwave.
extern "C"
{
ServerRecord ServerDesc[] =
{
{ "ImageFilterHandler", "LightWavin_gradient", GRADActivate },
{ "ImageFilterInterface", "LightWavin_gradient", GRADInterface },
{ NULL }
};
}
//These globals allow you to use the macros to add controls in the interface.
static LWPanControlDesc desc;
static LWValue ival={LWT_INTEGER},ivecval={LWT_VINT},
fval={LWT_FLOAT},fvecval={LWT_VFLOAT},sval={LWT_STRING};
//Activation function. This function tells Lightwave where to find all the
//functions it needs to run the plugin.
//
int GRADActivate(
long version,
GlobalFunc *global,
void *locPtr,
void *data
)
{
ImageFilterHandler *local = reinterpret_cast<ImageFilterHandler *>(locPtr);
if(version != 2) return AFUNC_BADVERSION;
local->create = GRADcreate;
local->destroy = GRADdestroy;
local->copy = GRADcopy;
local->load = GRADload;
local->save = GRADsave;
local->descln = GRADdescln;
local->process = GRADprocess;
local->flags = GRADflags;
return AFUNC_OK;
}
//Creation function
LWInstance GRADcreate(LWError *error)
{
GRADIENT *inst = new GRADIENT;
return(reinterpret_cast<LWInstance>(inst));
}
//Destroy function
void GRADdestroy(LWInstance inst)
{
if(inst)
{
GRADIENT *instToDelete = reinterpret_cast<GRADIENT *>(inst);
delete instToDelete;
return;
}
return;
}
//Copy function
LWError GRADcopy(LWInstance from, LWInstance to)
{
GRADIENT *first, *second;
first = reinterpret_cast<GRADIENT *>(from);
second = reinterpret_cast<GRADIENT *>(to);
*second = *first;
return NULL;
}
//Save function.
LWError GRADsave(LWInstance inst, const LWSaveState *lwss)
{
//Convert the instance pointer
GRADIENT *defInst = reinterpret_cast<GRADIENT*>(inst);
//Allocate the output string
char cOutputString[32];
//Enter the data
ostrstream ostr(cOutputString, 32);
ostr << defInst->cTop[0] << SPACE << defInst->cTop[1] << SPACE;
ostr << defInst->cTop[2];
ostr << SPACE << defInst->cBottom[0] << SPACE << defInst->cBottom[1];
ostr << SPACE << defInst->cBottom[2] << ends;
//Write the data to the scene file
lwss->write(lwss->writeData, cOutputString, 32);
return NULL;
}
//Load function
LWError GRADload(LWInstance inst, const LWLoadState *lwls)
{
//Convert the instance pointer
GRADIENT *defInst = reinterpret_cast<GRADIENT*>(inst);
//Allocate the input string
char cInputString[32];
//Get the data from the scene file
lwls->read(lwls->readData, cInputString, 32);
//Extract the data into the instance
istrstream istr(cInputString, 32);
istr >> defInst->cTop[0] >> defInst->cTop[1] >> defInst->cTop[2];
istr >> defInst->cBottom[0] >> defInst->cBottom[1] >> defInst->cBottom[2];
return NULL;
}
//Returns a descriptive line for the plugin
const char* GRADdescln(LWInstance inst)
{
return "Lightwavin' Plugin Tutorial";
}
//Tells LW which buffers the plugin will need
unsigned int GRADflags(LWInstance inst)
{
return NULL;
}
//Process - The fun stuff!
void GRADprocess(LWInstance inst, const FilterAccess *fa)
{
//Convert the instance
GRADIENT *defInst = reinterpret_cast<GRADIENT*>(inst);
//BufferValue pointers to process the image
BufferValue out[3], *r, *g, *b, *a;
//Create the monitor for our use
Monitor *mon = fa->monitor;
//Initialize the monitor
MON_INIT (mon, fa->height);
//Loop through the lines in the image
for (USHORT i = 0; i < fa->height; i++) {
r = fa->bufLine(LWBUF_RED, i);
g = fa->bufLine(LWBUF_GREEN, i);
b = fa->bufLine(LWBUF_BLUE, i);
a = fa->bufLine(LWBUF_ALPHA, i);
//This is the current percentage of the image that this line is
double dPercent = i;
dPercent /= fa->height;
#pragma warning(disable : 4244)
//Blend the gradient values
unsigned char currR = (defInst->cTop[0] * (1 - dPercent)) +
(defInst->cBottom[0] * dPercent );
unsigned char currG = (defInst->cTop[1] * (1 - dPercent)) +
(defInst->cBottom[1] * dPercent );
unsigned char currB = (defInst->cTop[2] * (1 - dPercent)) +
(defInst->cBottom[2] * dPercent );
#pragma warning(default : 4244)
//Divide the gradient by two (for a 50% blend with the image)
currR /= 2;
currG /= 2;
currB /= 2;
//Loop through the pixels in the line
for (USHORT j = 0; j < fa->width; j++)
{
out[0] = (r[j] / 2) + currR;
out[1] = (g[j] / 2) + currG;
out[2] = (b[j] / 2) + currB;
//Set the final pixels
fa->setRGB(j, i, out);
fa->setAlpha(j, i, a[i]);
}
//Step the monitor every 10th line
if ((i % 10) == 0) MON_INCR (mon, 10);
}
//Kill the monitor
MON_DONE (mon);
return;
}
//The interface function
int GRADInterface (
long version,
GlobalFunc *global,
LWInstance inst,
void *serverData
)
{
//Variables used to work the
LWPanelFuncs *panl;
LWPanelID panID;
LWControl *ctrl;
MessageFuncs *message;
GRADIENT *defInst = reinterpret_cast<GRADIENT *>(inst);
//Get the message function ready.
message = reinterpret_cast<MessageFuncs*>(global("Info Messages", GFUSE_TRANSIENT));
if (!message )
return AFUNC_BADGLOBAL;
//Get the panel function ready.
panl = reinterpret_cast<LWPanelFuncs*>(global(PANEL_SERVICES_NAME, GFUSE_TRANSIENT));
if(!panl)
{
(*message->error)("Unable to activate global "PANEL_SERVICES_NAME, " please add plugin lwpanels.p" );
return AFUNC_BADGLOBAL;
}
//This creates the panel in memory.
panID = panl->create("Lightwavin' Plugin Tutorial Interface", NULL);
//Add and set controls now.
{
RGB_CTL(panl, panID, "Color at top of image");
ctrl = panl->nextControl(panID, NULL);
SET_IVEC(ctrl, defInst->cTop[0], defInst->cTop[1], defInst->cTop[2]);
}
{
RGB_CTL(panl, panID, "Color at bottom of image");
ctrl = panl->nextControl(panID, ctrl);
SET_IVEC(ctrl, defInst->cBottom[0], defInst->cBottom[1], defInst->cBottom[2]);
}
//This displays the panel. It returns 0 if the user clicked cancel, 1 otherwise.
if( panl->open(panID, PANF_BLOCKING | PANF_CANCEL) )
{
ctrl = panl->nextControl(panID, NULL);
GET_IVEC(ctrl, defInst->cTop[0], defInst->cTop[1], defInst->cTop[2]);
ctrl = panl->nextControl(panID, ctrl);
GET_IVEC(ctrl, defInst->cBottom[0], defInst->cBottom[1], defInst->cBottom[2]);
}
//This kills the panel.
panl->destroy(panID);
return AFUNC_OK;
}